/**
 * 
 */
package com.etcfg.etlaunch;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.HashMap;
import java.util.Map;

public class RequestHandler implements Runnable {

	private ServerSocket serverSocket;
	private static ETLauncherApplication application;
	private static RequestHandler handler;
	public static final int PORT = 53573;

	private RequestHandler() throws IOException {

		serverSocket = new ServerSocket(PORT);

	}

	public static synchronized RequestHandler getHandler(
			ETLauncherApplication application) throws IOException {
		if (handler == null) {
			handler = new RequestHandler();
			RequestHandler.application = application;

		}
		return handler;

	}

	public static synchronized boolean isHandlerInitialized() {
		return handler != null;
	}

	@Override
	public void run() {
		while (true) {
			try {
				System.out.println("Waiting for request");
				Socket clientSocket = serverSocket.accept();
				System.out.println("Request received");

				OutputStream outputStream = clientSocket.getOutputStream();
				InputStream inputStream = clientSocket.getInputStream();

				BufferedReader bufferedReader = new BufferedReader(
						new InputStreamReader(inputStream, "ASCII"));
				HttpRequest httpRequest = parseRequest(bufferedReader);
				System.out.println(httpRequest);

				if (httpRequest.methodURI != null
						&& "GET".equals(httpRequest.method)) {
					String replace = httpRequest.methodURI.replace("/", "");
					try {
						Requests valueOf = Requests.valueOf(replace);
						valueOf.handleRequest(null, replace);
					} catch (Exception e) {
						e.printStackTrace();
					}

				}

				OutputStreamWriter outWriter = new OutputStreamWriter(
						outputStream);
				outWriter.write("HTTP/1.1 200 OK\r\n");
				outWriter.write("Date: Tue, 11 Jan 2011 13:09:20 GMT\r\n");
				outWriter.write("Expires: -1\r\n");
				outWriter.write("Cache-Control: private, max-age=0\r\n");
				outWriter.write("Content-type: text/html\r\n");
				outWriter.write("Server: vinit\r\n");
				outWriter.write("X-XSS-Protection: 1; mode=block\r\n");
				outWriter.write("\r\n");
				outWriter
						.write("<html><head><title>Hello</title></head><body>TestService</body></html>\r\n");

				outWriter.close();
				clientSocket.close();
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}

	}

	private class HttpRequest {
		Map<String, String> headers = new HashMap<String, String>();
		private String method;
		private String methodURI;
		private String requestBody;

		@Override
		public String toString() {
			return "HttpRequest [headers=" + headers + ", method=" + method
					+ ", methodURI=" + methodURI + ", requestBody="
					+ requestBody + "]";
		}

	}

	public HttpRequest parseRequest(BufferedReader reader) throws IOException {
		HttpRequest httpRequest = new HttpRequest();
		String methodLine = reader.readLine();
		String[] methodLineSplit = methodLine.split(" ");
		httpRequest.method = methodLineSplit[0];
		httpRequest.methodURI = methodLineSplit[1];

		String line;
		while ((line = reader.readLine()) != null) {
			if (line.length() == 0) {
				break;
			}
			String[] headerLineSplit = line.split(":");
			if (headerLineSplit.length > 1) {
				httpRequest.headers.put(headerLineSplit[0], headerLineSplit[1]);
			}
		}

		if ("GET".equals(httpRequest.method) == false) {
			StringBuilder requestBody = new StringBuilder();

			while ((line = reader.readLine()) != null) {
				if (line.length() == 0) {
					break;
				}
				requestBody.append(line + "\r\n");

			}
			httpRequest.requestBody = requestBody.toString();
		}
		return httpRequest;
	}

	public enum Requests {
		SHOW_WINDOW {
			@Override
			public void handleRequest(Map<String, String> headers, String body) {
				application.getMainWindow().getFrame().setVisible(true);
			}
		};

		public abstract void handleRequest(Map<String, String> headers,
				String body);
	}

}